package com.cennavi.minemapdemo.net;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by lijingru on 2017/9/19.
 */

public class OkHttp3Utils {
    private static OkHttpClient client = null;

    private OkHttp3Utils() {
    }

    public static OkHttpClient getInstance() {
        if (client == null) {
            synchronized (OkHttp3Utils.class) {
                if (client == null) {
                    client = new OkHttpClient();
//                    OkHttpClient.Builder builder = new OkHttpClient.Builder()
//                            .connectTimeout(15, TimeUnit.SECONDS)
//                            .writeTimeout(20, TimeUnit.SECONDS)
//                            .readTimeout(20, TimeUnit.SECONDS);
//                    client = builder.build();
                    setTimeout();
                }
            }
        }
        return client;
    }

    private static void setTimeout() {
        client.newBuilder()
                .connectTimeout(10, TimeUnit.SECONDS)//10 秒连接超时
                .writeTimeout(10, TimeUnit.SECONDS)//10m秒写入超时
                .readTimeout(10, TimeUnit.SECONDS)//10秒读取超时
                .build();
    }

    /**
     * Get请求
     *
     * @param url
     * @param callback
     */
    public static void doGet(String url, Callback callback) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = getInstance().newCall(request);
        call.enqueue(callback);
    }

    /**
     * Get请求 同步
     *
     * @param url
     */
    public static Response doGetT(String url) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .build();
        return getInstance().newCall(request).execute();

    }

    /**
     * Post请求发送键值对数据
     *
     * @param url
     * @param mapParams
     * @param callback
     */
    public static void doPost(String url, Map<String, Object> mapParams, Callback callback) {
        FormBody.Builder builder = new FormBody.Builder();
        for (String key : mapParams.keySet()) {
            builder.add(key, mapParams.get(key) + "");
        }
        Request request = new Request.Builder()
                .url(url)
                .post(builder.build())
                .build();
        Call call = getInstance().newCall(request);
        call.enqueue(callback);
    }

    /**
     * Post请求发送键值对数据 同步
     *
     * @param url
     * @param mapParams
     */
    public static Response doPostT(String url, Map<String, Object> mapParams) throws IOException {
        FormBody.Builder builder = new FormBody.Builder();
        for (String key : mapParams.keySet()) {
            builder.add(key, mapParams.get(key) + "");
        }
        Request request = new Request.Builder()
                .url(url)
                .post(builder.build())
                .build();
        return getInstance().newCall(request).execute();
    }

    /**
     * Post请求发送JSON数据
     *
     * @param url
     * @param jsonParams
     * @param callback
     */
    public static void doPost(String url, String jsonParams, Callback callback) {
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8")
                , jsonParams);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Call call = getInstance().newCall(request);
        call.enqueue(callback);
    }

    /**
     * Post请求发送JSON数据 同步
     *
     * @param url
     * @param jsonParams
     */
    public static Response doPostT(String url, String jsonParams) throws IOException {
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8")
                , jsonParams);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        return getInstance().newCall(request).execute();
    }

    /**
     * 上传文件
     *
     * @param url
     * @param pathName
     * @param fileName
     * @param fileType
     * @param mapParams 键值对
     * @param callback
     */
    public static void doFile(String url, String pathName, String fileName, String fileType, Map<String, Object> mapParams, Callback callback) {
        MediaType MEDIA_TYPE_PNG = MediaType.parse("image/jpg");

        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        if (mapParams == null) {
            builder.addFormDataPart(fileType, fileName,
                    RequestBody.create(MEDIA_TYPE_PNG, new File(pathName)));

        } else {
            for (String key : mapParams.keySet()) {
                builder.addFormDataPart(key, mapParams.get(key) + "");
            }

            builder.addFormDataPart(fileType, fileName,
                    RequestBody.create(MEDIA_TYPE_PNG, new File(pathName)));

        }

        //发出请求参数
        Request request = new Request.Builder()
                .url(url)
                .post(builder.build())
                .build();
        Call call = getInstance().newCall(request);
        call.enqueue(callback);
    }

    /**
     * 上传文件同步
     *
     * @param url
     * @param pathName
     * @param fileName
     * @param fileType
     * @param mapParams 键值对
     */
    public static Response doFileT(String url, String pathName, String fileName, String fileType, Map<String, Object> mapParams) throws IOException {
        MediaType MEDIA_TYPE_PNG = MediaType.parse("image/jpg");

        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        if (mapParams == null) {
            builder.addFormDataPart(fileType, fileName,
                    RequestBody.create(MEDIA_TYPE_PNG, new File(pathName)));

        } else {
            for (String key : mapParams.keySet()) {
                builder.addFormDataPart(key, mapParams.get(key) + "");
            }

            builder.addFormDataPart(fileType, fileName,
                    RequestBody.create(MEDIA_TYPE_PNG, new File(pathName)));

        }

        //发出请求参数
        Request request = new Request.Builder()
                .url(url)
                .post(builder.build())
                .build();
        return getInstance().newCall(request).execute();
    }

    /**
     * 根据文件路径判断MediaType
     *
     * @param path
     * @return
     */
    private static String judgeType(String path) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String contentTypeFor = fileNameMap.getContentTypeFor(path);
        if (contentTypeFor == null) {
            contentTypeFor = "application/octet-stream";
        }
        return contentTypeFor;
    }

    /**
     * 下载文件
     *
     * @param url
     * @param fileDir
     * @param fileName
     */
    public static void downFile(String url, final String fileDir, final String fileName) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = getInstance().newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                try {
                    is = response.body().byteStream();
                    File file = new File(fileDir, fileName);
                    fos = new FileOutputStream(file);
                    //---增加的代码---
                    //TODO 计算进度
                    long totalSize = response.body().contentLength();
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        sum += len;
                        //progress就是进度值
                        int progress = (int) (sum * 1.0f / totalSize * 100);
                        //---增加的代码---
                        fos.write(buf, 0, len);
                    }
                    fos.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (is != null) is.close();
                    if (fos != null) fos.close();
                }
            }
        });
    }


    /********OkHttp3 使用例子*******/
    protected void test() {
        /*
         * Get请求
         * 参数一：请求Url
         * 参数二：请求回调
         */
        OkHttp3Utils.doGet("https://www.so.com/", new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
//                    tv.setText(response.body().string());
                }
                //关闭防止内存泄漏
                if (response.body() != null) {
                    response.body().close();
                }
            }
        });


        /*
         * Post请求
         * 参数一：请求Url
         * 参数二：请求的键值对
         * 参数三：请求回调
         */
        Map<String, Object> map = new HashMap<>();
        map.put("username", "Hensen");
        map.put("password", "123456");

        OkHttp3Utils.doPost("http://192.168.31.109:8080/test.php", map, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });



        /*
         * Post请求
         * 参数一：请求Url
         * 参数二：请求的JSON
         * 参数三：请求回调
         */
        String json = "{\"name\":\"Hensen\"}";

        OkHttp3Utils.doPost("http://192.168.0.8:8080/test.php", json, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });



        /*
         * 上传文件
         * 参数一：请求Url
         * 参数二：保存文件的路径名
         * 参数三：保存文件的文件名
         * 参数四：键值对
         * 参数四：请求回调
         */
//        OkHttp3Utils.doFile("http://192.168.0.8:8080/WD/admin.php?a=ajaxuploadimage&&c=Image",
//                "/data/data/com.handsome.app4/logoa.jpg", "logoa.jpg",null, new Callback() {
//                    @Override
//                    public void onFailure(Call call, IOException e) {
//
//                    }
//
//                    @Override
//                    public void onResponse(Call call, Response response) throws IOException {
//                        response.body().string();
//                    }
//                });


        /*
         * 下载文件
         * 参数一：请求Url
         * 参数二：保存文件的路径名
         * 参数三：保存文件的文件名
         */
        OkHttp3Utils.downFile("http://shouji.360tpcdn.com/160804/a05b75b7779f7a4afae83601c195ed2b" +
                        "/com.qihoo.haosou_708.apk"
                , "/data/data/com.handsome.app4/", "aqy.apk");

    }


}
